<script lang="ts" setup>
import {
  reactive,
  ref,
  shallowRef,
  onMounted,
  onActivated,
  defineAsyncComponent,
  provide
} from 'vue'
import { useMap } from '@/hooks/useMap'
import { useActivated } from '@/hooks/useActivated'
import { useRoute } from 'vue-router'
import SearchPlace from '@/components/map/SearchPlace.vue'
import bikeImg from '@/assets/map/bikeLocation/bike.png'
import { queryShortTermBikeLocation } from '@/api/bike'
import { bikeLocationDataType, coordinatesType } from '@/api/bike/types/bike'
import { getToken } from '@/utils/cache/cookies'
import { ElMessage } from 'element-plus'
import GoButton from '@/components/basic/GoButton.vue'
defineOptions({
  name: 'TimeBikeAMap'
})
const route = useRoute()
const params = reactive({
  storeId: route.query.storeId as string
})

const center = reactive({
  longtitude: 0,
  latitude: 0
})
const loading = ref<boolean>(false)
const isInit = ref<boolean>(false)
const mapContainer = ref<HTMLDivElement>()
const markers = shallowRef<AMap.LabelMarker[]>([])
const bikeLocations = ref<bikeLocationDataType[]>([])
const coordinates = ref<AMap.LngLat[]>([])
const labelsLayer = shallowRef<AMap.LabelsLayer>()
const { map, auto, initAmap, getAddress, placeSearch, mousetool } = useMap(mapContainer, [
  Number(center.longtitude),
  Number(center.latitude)
])
/** 地图初始化 */
const getIcon: () => AMap.LabelMarkerIconOptions = () => {
  return {
    type: 'image', //图标类型，现阶段只支持 image 类型
    image: bikeImg, //可访问的图片 URL
    size: [59, 63], //图片尺寸
    clipOrigin: [0, 0],
    clipSize: [59, 63]
  }
}
const getData = async () => {
  try {
    loading.value = true
    const res = await queryShortTermBikeLocation({
      storeId: route.query.storeId as string,
      token: getToken() ?? '',
      showReturnLocation: 0
    })
    if (res.statusCode === '0') {
      bikeLocations.value = res.data.bikeLocationData
      const centerData = bikeLocations.value[0]
      center.longtitude = centerData.longtitude
      center.latitude = centerData.latitude
      coordinates.value = handleCoordinates(res.data.coordinates)
      await handleCoverInit()
    } else {
      ElMessage.error('暂无数据')
    }
    loading.value = false
  } catch (error) {
    console.error(error)
  }
}
const handleCoverInit = async () => {
  if (isInit.value && map.value) {
    if (labelsLayer.value) {
      markers.value = []
      labelsLayer.value.clear()
      map.value.removeLayer(labelsLayer.value)
      map.value.clearMap()
    }
    map.value?.setCenter([center.longtitude, center.latitude])
    labelsLayer.value = new AMap.LabelsLayer({
      zooms: [3, 20],
      zIndex: 1000,
      collision: false, //该层内标注是否避让
      allowCollision: true //不同标注层之间是否避让
    })

    map.value.add(labelsLayer.value)
    const normalMarker = new AMap.Marker({
      anchor: 'bottom-center',
      offset: [0, -63]
    })
    bikeLocations.value?.forEach((point: bikeLocationDataType) => {
      const curData = {
        position: new AMap.LngLat(Number(point.longtitude) ?? 0, Number(point.latitude) ?? 0),
        icon: getIcon(),
        rank: 1,
        zIndex: 16
      }
      const labelMarker = new AMap.LabelMarker(curData)
      markers.value?.push(labelMarker)
      labelMarker.on('click', async (e: any) => {
        const position = e.data.data && e.data.data.position
        if (position) {
          const address: any = await getAddress(position[0], position[1])
          normalMarker.setContent(createContent(address))
          normalMarker.setPosition(position)
          map.value?.add(normalMarker)
        }
      })
    })
    labelsLayer.value.add(markers.value)
    if (coordinates.value.length > 0) {
      const polygon = new AMap.Polygon({
        path: coordinates.value,
        strokeColor: '#418DFF',
        strokeOpacity: 1,
        strokeWeight: 3,
        fillColor: '#418DFF',
        fillOpacity: 0.1,
        strokeStyle: 'dashed'
      })
      map.value?.add(polygon)
    }
  }
}
/** 转换数据用于初始化运营区域 */
const handleCoordinates = (data: coordinatesType[]) => {
  return data.map(
    (location: coordinatesType) => new AMap.LngLat(location.longtitude, location.latitude)
  )
}
const createContent = (address: string) => {
  return `<div class="map-infowindow_location">
                  <span>车辆位置:${address}</span>
              </div>
              `
}
onMounted(async () => {
  isInit.value = await initAmap()
  if (route.query.storeId) getData()
})

/** 查看区域内车辆 */
const ViewRegional = defineAsyncComponent(() => import('@/components/map/ViewRegional.vue'))
const inview = ref<bikeLocationDataType[]>([])
const overlayGroup = ref<AMap.OverlayGroup | null>(null)
const handleSquare = () => {
  mousetool.value.rectangle({
    fillColor: '#FF6D75',
    fillOpacity: 0.1,
    strokeWeight: 3,
    strokeColor: '#FF6D75',
    strokeOpacity: 1
  })
  overlayGroup.value = new AMap.OverlayGroup()
  mousetool.value.on('draw', handleDrawRectangle)
}
const handleDrawRectangle = (e: any) => {
  if (overlayGroup.value?.getOverlays().length) overlayGroup.value?.hide()
  overlayGroup.value?.addOverlay(e.obj)
  const path = e.obj.getPath().map((p: AMap.LngLat) => [p.getLng(), p.getLat()])
  const lastInView = [...inview.value]
  inview.value =
    bikeLocations.value?.filter((bike) =>
      AMap.GeometryUtil.isPointInRing([+bike.longtitude, +bike.latitude], path)
    ) ?? []
  if (!inview.value.length) inview.value = lastInView
}
const handleCloseMouseTool = () => {
  mousetool.value?.close(true)
  inview.value = []
  overlayGroup.value?.clearOverlays()
  mousetool.value.off('draw', handleDrawRectangle)
}
provide('handleCloseMouseTool', handleCloseMouseTool)
/** 处理是否缓存 */
onActivated(() => {
  params.storeId = route.query.storeId as string
})
useActivated(params, { params }, [{ key: 'storeId', path: 'params.storeId' }], getData, [])
</script>

<template>
  <div class="xy-map-container">
    <div ref="mapContainer" id="map-container" v-loading="loading">
      <search-place :auto="auto" :map="map!" :place-search="placeSearch" />
      <div class="view-regional-bike-control-container">
        <go-button icon-name="squarecontrol" @click="handleSquare">
          <template #text>
            <span>查看区域内车辆</span>
          </template>
        </go-button>
      </div>
      <Transition
        enter-active-class="animate__animated animate__bounceInRight"
        leave-active-class="animate__animated animate__bounceOutRight"
        mode="out-in"
      >
        <view-regional v-if="inview.length" :data="inview" />
      </Transition>
    </div>
  </div>
</template>

<style scoped>
.view-regional-bike-control-container {
  position: absolute;
  top: 20px;
  right: 20px;
  z-index: 200;
  background: #fff;
  padding: 0 10px;
  border-radius: 5px;
  box-shadow: 0px 3px 6px 1px rgba(0, 0, 0, 0.1);
}
</style>
